#include "stdafx.h"
#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace ShowClassTest
{		
	TEST_CLASS(ShowClassTest)
	{
	public:
		
		TEST_METHOD(DisplayTypeShowDefault)
		{
			//This is not a full unit test
			//This is a fake display function
			//This is to test the functionality of show default
			std::string outputString;
			std::ostringstream expectedStream;
			
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;
			
			todoTMPtr = new TextManipulatorStubWithFlexiTime("testingTodo.txt");
			doneTMPtr = new TextManipulatorStubWithFlexiTime("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);
			
			outputString = cmdPtr->executeInput("");

			expectedStream << std::endl;
			expectedStream << "This test should show ALL Floating Task, ALL Deadline Task, and schedule of \"today\"" << std::endl;
			expectedStream << "Floating Task: 3" << std::endl;
			expectedStream << "Deadline Task: 2" << std::endl;
			expectedStream << "Scheduled Task: 1 if it is a monday/sunday today, 0 for other days" << std::endl;

			Assert::AreEqual(expectedStream.str(), outputString);

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}


		TEST_METHOD(DisplayTypeShowDay_140214)
		{
			//This is not a full unit test
			//This is a fake display function
			//This is to test show day with a specific date given
			std::string outputString;
			std::ostringstream expectedStream;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;
			
			todoTMPtr = new TextManipulatorStubWithFlexiTime("testingTodo.txt");
			doneTMPtr = new TextManipulatorStubWithFlexiTime("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			expectedStream << std::endl;
			expectedStream << "This test should show Deadline Task of the day, and schedule of the particular day entered" << std::endl;
			expectedStream << "Deadline Task: 1 - Order Lambo for valentine, with location" << std::endl;
			expectedStream << "Scheduled Task: 2 - 1 partial time, 1 timed" << std::endl;

			outputString = cmdPtr->executeInput("14/02/14");
			Assert::AreEqual(expectedStream.str(), outputString);

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(DisplayTypeShowDay_lastmonday)
		{
			//This is not a full unit test
			//This is a fake display function
			//This is to test show day with a day
			std::string outputString;
			std::ostringstream expectedStream;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStubWithFlexiTime("testingTodo.txt");
			doneTMPtr = new TextManipulatorStubWithFlexiTime("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			expectedStream << std::endl;
			expectedStream << "This test should show Deadline Task of the day, and schedule of the particular day entered" << std::endl;
			expectedStream << "Deadline Task: 0" << std::endl;
			expectedStream << "Scheduled Task: 1 timed" << std::endl;

			outputString = cmdPtr->executeInput("last monday");
			Assert::AreEqual(expectedStream.str(), outputString);

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(DisplayTypeShowTodo)
		{
			//This is not a full unit test
			//This is a fake display function
			//This is to test the functionality of show todo
			std::string outputString;
			std::ostringstream expectedStream;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStubWithFlexiTime("testingTodo.txt");
			doneTMPtr = new TextManipulatorStubWithFlexiTime("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			expectedStream << std::endl;
			expectedStream << "This test should show ALL Floating Task and ALL Deadline Task" << std::endl;
			expectedStream << "Floating Task: 3" << std::endl;
			expectedStream << "Deadline Task: 2" << std::endl;

			outputString = cmdPtr->executeInput("todo");
			Assert::AreEqual(expectedStream.str(), outputString);

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(DisplayTypeShowWeek_week140214)
		{
			//This is not a full unit test
			//This is a fake display function
			//This is a test the functioality of show week
			std::string outputString;
			std::ostringstream expectedStream;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStubWithFlexiTime("testingTodo.txt");
			doneTMPtr = new TextManipulatorStubWithFlexiTime("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);
			
			outputString = cmdPtr->executeInput("week 14/02/14");
			
			expectedStream << std::endl;
			expectedStream << "This test should show Deadline Task and schedule for the week" << std::endl;
			expectedStream << "Deadline Task: 2" << std::endl;
			expectedStream << "Scheduled Task: 13 unique - 3, 4, 5, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17 - at least one per day" << std::endl;
			
			Assert::AreEqual(expectedStream.str(), outputString);

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}


		TEST_METHOD(DisplayTypeShowWeek_thisweek)
		{
			//This is not a full unit test
			//this is a fake display function
			//This is to test the functionality of week using this week
			std::string outputString;
			std::ostringstream expectedStream;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStubWithFlexiTime("testingTodo.txt");
			doneTMPtr = new TextManipulatorStubWithFlexiTime("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			expectedStream << std::endl;
			expectedStream << "This test should show Deadline Task and schedule for the week" << std::endl;
			expectedStream << "Deadline Task: 0" << std::endl;
			expectedStream << "Scheduled Task: 2 - monday and sunday" << std::endl;

			outputString = cmdPtr->executeInput("this week");
			Assert::AreEqual(expectedStream.str(), outputString);

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}


		TEST_METHOD(DisplayTypeDoneDefault)
		{
			//This is not a full unit test
			//This is a fake display function
			//This is to test a functionality of done default
			std::string outputString;
			std::ostringstream expectedStream;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStubWithFlexiTime("testingTodo.txt");
			doneTMPtr = new TextManipulatorStubWithFlexiTime("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			expectedStream << std::endl;
			expectedStream << "This test should show All DONE Floating and Deadline Task" << std::endl;
			expectedStream << "Floating Task: 3" << std::endl;
			expectedStream << "Deadline Task: 2" << std::endl;

			outputString = cmdPtr->executeInput("done");
			Assert::AreEqual(expectedStream.str(), outputString);

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(DisplayTypeDoneDay_130214)
		{
			//This is not a full unit test
			//This is a fake display function
			//This is a functionality of done day with a particular date
			std::string outputString;
			std::ostringstream expectedStream;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStubWithFlexiTime("testingTodo.txt");
			doneTMPtr = new TextManipulatorStubWithFlexiTime("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			expectedStream << std::endl;
			expectedStream << "This test should show All DONE Floating and Deadline Task" << std::endl;
			expectedStream << "Floating Task: 3" << std::endl;
			expectedStream << "Deadline Task: 1" << std::endl;

			outputString = cmdPtr->executeInput("done 13/02/14");
			Assert::AreEqual(expectedStream.str(), outputString);

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(DisplayTypeDoneWeek_week130214)
		{
			//This is not a full unit test
			//This is a fake display function
			//This is a test of the functionality of done week
			std::string outputString;
			std::ostringstream expectedStream;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStubWithFlexiTime("testingTodo.txt");
			doneTMPtr = new TextManipulatorStubWithFlexiTime("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			expectedStream << std::endl;
			expectedStream << "This test should show All DONE Floating and Deadline Task" << std::endl;
			expectedStream << "Floating Task: 3" << std::endl;
			expectedStream << "Deadline Task: 2" << std::endl;

			outputString = cmdPtr->executeInput("done week 13/02/14");
			Assert::AreEqual(expectedStream.str(), outputString);

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}
		
		TEST_METHOD(TestStoreDisplayedFunctionalityNotRepeated_ShowDefault)
		{
			//This unit test tests the storeDisplayed functionality
			//storeDisplyed will update the static variables in command class after a display is sucessfully shown 
			//In this test the storeDisplayed functionality when the taskIndexes are not repeated are tested			
			//Also tests if the _displayedTMPtr is pointing to the correct file("testingTodo.txt")
			
			std::vector<int> expectedTaskIndexVector;
			std::vector<int> taskIndexVector;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStub("testingTodo.txt");
			doneTMPtr = new TextManipulatorStub("testingDone.txt");

			TestMethods testMethods(todoTMPtr, doneTMPtr);
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			cmdPtr->executeInput("");			
			taskIndexVector = testMethods.executeGetDisplayedTask();
			
			expectedTaskIndexVector.push_back(0);
			expectedTaskIndexVector.push_back(1);
			expectedTaskIndexVector.push_back(2);
			expectedTaskIndexVector.push_back(7);
			expectedTaskIndexVector.push_back(10);

			Assert::IsTrue(todoTMPtr == testMethods.executeGetDisplayedTMPtr());
			Assert::AreEqual(expectedTaskIndexVector.size(), taskIndexVector.size());

			for(unsigned int i = 0; i < expectedTaskIndexVector.size() ; i++) {
				Assert::AreEqual(expectedTaskIndexVector[i], taskIndexVector[i]);
			}

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(TestStoreDisplayedFunctionalityRepeated_week140214)
		{
			//This unit test tests the storeDisplayed functionality
			//storeDisplyed will update the static variables in command class after a display is sucessfully shown 
			//In this test the storeDisplayed functionality when the taskIndexes are repeated and are tested using userInput week 14/02/14			
			//Also tests if the _displayedTMPtr is pointing to the correct file("testingTodo.txt")

			std::vector<int> expectedTaskIndexVector;
			std::vector<int> taskIndexVector;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStub("testingTodo.txt");
			doneTMPtr = new TextManipulatorStub("testingDone.txt");

			TestMethods testMethods(todoTMPtr, doneTMPtr);
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			cmdPtr->executeInput("week 14/02/14");			
			taskIndexVector = testMethods.executeGetDisplayedTask();
			
			for(int i = 3; i <= 17; i++) {
				expectedTaskIndexVector.push_back(i);
			}

			Assert::IsTrue(todoTMPtr == testMethods.executeGetDisplayedTMPtr());			
			Assert::AreEqual(expectedTaskIndexVector.size(), taskIndexVector.size());
			
			for(unsigned int i = 0; i < expectedTaskIndexVector.size() ; i++) {
				Assert::AreEqual(expectedTaskIndexVector[i], taskIndexVector[i]);
			}

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(TestStoreDisplayedFunctionalityNotRepeated_DoneDefault)
		{
			//This unit test tests the storeDisplayed functionality
			//storeDisplyed will update the static variables in command class after a display is sucessfully shown 
			//In this test the storeDisplayed functionality when the taskIndexes are not repeated are tested
			//Also tests if the _displayedTMPtr is pointing to the correct file("testingDone.txt")

			std::vector<int> expectedTaskIndexVector;
			std::vector<int> taskIndexVector;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStub("testingTodo.txt");
			doneTMPtr = new TextManipulatorStub("testingDone.txt");

			TestMethods testMethods(todoTMPtr, doneTMPtr);
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			cmdPtr->executeInput("done");			
			taskIndexVector = testMethods.executeGetDisplayedTask();
			
			expectedTaskIndexVector.push_back(0);
			expectedTaskIndexVector.push_back(1);
			expectedTaskIndexVector.push_back(2);
			expectedTaskIndexVector.push_back(7);
			expectedTaskIndexVector.push_back(10);

			Assert::IsTrue(doneTMPtr == testMethods.executeGetDisplayedTMPtr());
			Assert::AreEqual(expectedTaskIndexVector.size(), taskIndexVector.size());

			for(unsigned int i = 0; i < expectedTaskIndexVector.size() ; i++) {
				Assert::AreEqual(expectedTaskIndexVector[i], taskIndexVector[i]);
			}

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(TestStoreDisplayedFunctionalityRepeated_doneweek140214)
		{
			//This unit test tests the storeDisplayed functionality
			//storeDisplyed will update the static variables in command class after a display is sucessfully shown 
			//In this test the storeDisplayed functionality when the taskIndexes are repeated and are tested using userInput done week 14/02/14			
			//Also tests if the _displayedTMPtr is pointing to the correct file("testingDone.txt")

			std::vector<int> expectedTaskIndexVector;
			std::vector<int> taskIndexVector;
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStub("testingTodo.txt");
			doneTMPtr = new TextManipulatorStub("testingDone.txt");

			TestMethods testMethods(todoTMPtr, doneTMPtr);
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			cmdPtr->executeInput("done week 14/02/14");			
			taskIndexVector = testMethods.executeGetDisplayedTask();
			
			expectedTaskIndexVector.push_back(0);
			expectedTaskIndexVector.push_back(1);
			expectedTaskIndexVector.push_back(2);
			expectedTaskIndexVector.push_back(7);
			expectedTaskIndexVector.push_back(10);

			Assert::IsTrue(doneTMPtr == testMethods.executeGetDisplayedTMPtr());
			Assert::AreEqual(expectedTaskIndexVector.size(), taskIndexVector.size());
			
			for(unsigned int i = 0; i < expectedTaskIndexVector.size() ; i++) {
				Assert::AreEqual(expectedTaskIndexVector[i], taskIndexVector[i]);
			}

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}


		TEST_METHOD(DisplayInvalidDateTimeException_invalidinput)
		{
			//This unit test tests for the exceptions
			//INPUTERROR_INVALIDDATETIME will be thrown when invalid input is keyed

			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStub("testingTodo.txt");
			doneTMPtr = new TextManipulatorStub("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			try {
				cmdPtr->executeInput("invalid input");
			}
			catch (std::exception& exception){
				Assert::AreEqual(INPUTERROR_INVALIDDATETIMESHOWSEARCH.c_str(), exception.what());
			}
			
			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(DisplayInvalidCommandException_invalidinputdone)
		{
			//This unit test tests for the exceptions
			//INPUTERROR_INVALIDCOMMAND will be thrown when the done keyword does not immediately follow show
			
			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStub("testingTodo.txt");
			doneTMPtr = new TextManipulatorStub("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			try {
				cmdPtr->executeInput("invalid input done");
			}
			catch (std::exception& exception){
				Assert::AreEqual(INPUTERROR_INVALIDSHOWDONE.c_str(), exception.what());
			}

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}

		TEST_METHOD(DisplayRepeatedAttributeKeywordException_doneblahdone)
		{
			//This unit test tests for the exceptions
			//INPUTERROR_REPEATATTRIBUTEKEYWORDS will be thrown when there is more than one done keyword

			Manipulator* todoTMPtr;
			Manipulator* doneTMPtr;
			Command* cmdPtr;

			todoTMPtr = new TextManipulatorStub("testingTodo.txt");
			doneTMPtr = new TextManipulatorStub("testingDone.txt");
			cmdPtr = new Show(todoTMPtr, doneTMPtr);

			try {
				cmdPtr->executeInput("done blah done");
			}
			catch (std::exception& exception){
				Assert::AreEqual(INPUTERROR_REPEATATTRIBUTEKEYWORDS.c_str(), exception.what());
			}

			delete cmdPtr;
			delete todoTMPtr;
			delete doneTMPtr;
		}
	};
}